// SAMPLE USAGE
// var my_formula = new Formula("@Concat(@FIELDNAME1, @FIELDNAME2, @FIELDNAME3)",function(){
    // you may use this callback
// });
// var this_true_value = my_formula.getEvaluation();










function Formula(formula,CB){
	if(typeof CB == "undefined"){
		//catch undefined
	}

	this.formula = formula;
	this.processedFormula = "";
	//getting fieldnames with at sign
	this.getSplittedFNWithAtSign = formula.match(/@[a-zA-Z0-9_]*\[[A-Za-z0-9]*\]|@[a-zA-Z0-9_]*/g);
	//getting fieldnames without at sign
	this.getSplittedFieldNames = [];
	if(this.getSplittedFNWithAtSign != null){
		for(var ctr_i = 0 ; ctr_i < this.getSplittedFNWithAtSign.length ; ctr_i ++){
			this.getSplittedFieldNames.push( this.getSplittedFNWithAtSign[ctr_i].replace(/@/g,"") );
		}
	}

	//call back with this keyword
	if(typeof CB != "undefined"){
		this.callBack = CB;
		this.callBack();
	}
}

Formula.prototype.getMyFormula = function() {
	return this.formula;
};

Formula.prototype.getProcessedFormula = function() {
	var toProcessFormula = "";
	var splittedFieldNames = "";
	if(this.getSplittedFNWithAtSign != null){
		toProcessFormula = this.formula;
		var formula_keywords = ["Status", "Requestor", "RequestID", "CurrentUser", "TrackNo", "Department","Today","Now"]; /// keywords is an element too
		splittedFieldNames = this.getSplittedFieldNames;
		for(var ii = 0 ; ii < splittedFieldNames.length ; ii++ ){
			var element_in_progress = $('[name="'+splittedFieldNames[ii]+'"]');
			var fn_progress_keywords = splittedFieldNames[ii];
			
			if(element_in_progress.length >= 1 ){ // kapag existing nga talaga si fieldname KASAMA NA RIN RITO UNG FORMULA KEYWORDS
				
				if(formula_keywords.indexOf(fn_progress_keywords) >= 0){ // KAPAG KEYWORD KASi EXISTING DIN UNG MGA TRACK NO KEWORDS
					
					if(fn_progress_keywords == "CurrentUser"){ // I MODIFY SPECIFIC KEYWORDS VALUE
						var re = new RegExp("@"+fn_progress_keywords+"","g");
						var CurrentUserName = "";
						if(typeof element_in_progress.attr("current-user-name") != "undefined"){
							CurrentUserName = element_in_progress.attr("current-user-name");
						}
						toProcessFormula = toProcessFormula.replace(re, "\"" + cleanStringValue(CurrentUserName) + "\"");
					}else{										// DEFAULT FOR KEYWORDS
						var re = new RegExp("@"+fn_progress_keywords+"","g");
						toProcessFormula = toProcessFormula.replace(re, "\"" + cleanStringValue(element_in_progress.val()) + "\"");
					}

				}else{	//..............................................KAPAG HINDI KEYWORD
				
					var re = new RegExp("@"+splittedFieldNames[ii]+"","g");
					if(element_in_progress.val().length >= 1){ // not empty value for a specific element
						if( $.isNumeric( element_in_progress.val() ) ){//kapag number ung laman nung fieldname
							toProcessFormula = toProcessFormula.replace(re, Number(element_in_progress.val()) );
						}else{ // kapag hindi number ung laman ni fieldname
							if(typeof element_in_progress.attr("data-input-type") != "undefined"){
								if(element_in_progress.attr("data-input-type") == "Currency"){
									toProcessFormula = toProcessFormula.replace(re,
										Number( cleanStringValue( cleanNumberValue(
											element_in_progress.val()
										) ) )
									);
								}else if(element_in_progress.attr("data-input-type") == "Number"){
									toProcessFormula = toProcessFormula.replace(re,
										Number( cleanStringValue( cleanNumberValue(
											element_in_progress.val()
										) ) )
									);
								}else if(element_in_progress.attr("data-input-type") == "Text"){
									toProcessFormula = toProcessFormula.replace(re, "\"" + cleanStringValue(element_in_progress.val()) + "\"" );
								}
							}else{ // DEFAULT
								toProcessFormula = toProcessFormula.replace(re, "\"" + cleanStringValue(element_in_progress.val()) + "\"" );
							}
						}
					}else{//kapag walang lamang ung value nung fieldname
						toProcessFormula = toProcessFormula.replace(re, "\"" + cleanStringValue(element_in_progress.val()) + "\"" );
					}
				
				}
			}else if(element_in_progress.length <= 0){//keywords and function names .... HINDI NA FIELDNAMES ITO
				
				if(formula_keywords.indexOf(fn_progress_keywords) >= 0){ // KAPAG keywords nga talaga
					if(fn_progress_keywords == "Today"){
						var this_today = new Date(getUpdatedServerTime());
                        this_today = this_today.getFullYear() + "-" + StrRight("0" + (this_today.getMonth() + 1), 2) + "-" + StrRight("0" + this_today.getDate(), 2);
                        var re = new RegExp("@"+fn_progress_keywords+"","g");
                        toProcessFormula = toProcessFormula.replace(re, "\"" + cleanStringValue(this_today) + "\"" );
					}else if(fn_progress_keywords == "Now"){
						var this_today = new Date(getUpdatedServerTime());
                        this_today = this_today.getFullYear() + "-" + StrRight("0" + (this_today.getMonth() + 1), 2) + "-" + StrRight("0" + this_today.getDate(), 2) + " " + StrRight("0" + this_today.getHours(), 2) + ":" + StrRight("0" + this_today.getMinutes(), 2) + ":" + StrRight("0" + this_today.getSeconds(), 2);
						var re = new RegExp("@"+fn_progress_keywords+"","g");
						toProcessFormula = toProcessFormula.replace(re, "\"" + cleanStringValue(this_today) + "\"" );
					}else if(fn_progress_keywords == "RequestID"){
						var request_id_ele = $('[name="ID"]');
						var rid_val = request_id_ele.val();
						var re = new RegExp("@"+fn_progress_keywords+"","g");
						toProcessFormula = toProcessFormula.replace(re, cleanStringValue(rid_val) );
					}
				}
			}
		}
	}else{ // KAPAG WALANG NAKITANG MAY AT SAYN
		toProcessFormula = this.formula;
	}


	toProcessFormula = toProcessFormula.replace(/@/g,"");
	this.processedFormula = toProcessFormula;
	return toProcessFormula;
};

Formula.prototype.getEvaluation = function() {
	var processed_formula = this.getProcessedFormula();
	var evaluation_status = false;
	try{
		eval(processed_formula)
		evaluation_status = true;
	}catch(err){
		evaluation_status = false;
	}
	if(evaluation_status == true){
		return eval(processed_formula);
	}else{
		return "Invalid formula";
	}
};














function getUpdatedServerTime() {
    if (typeof $("body").data() != "undefined") {
        if (typeof $("body").data().get_counter_data != "undefined") {
            if (typeof $("body").data().get_counter_data.getDateTime != "undefined") {
                return $("body").data().get_counter_data.getDateTime;
            }
        }
    }
    return "";
}

function cleanStringValue(value){
	var clean_string_progress = ""+value;
	clean_string_progress = clean_string_progress.replace(/\\/g, "\\\\");
    clean_string_progress = clean_string_progress.replace(/\"/g, "\\\"");
    return clean_string_progress;
}
function cleanNumberValue(value){
	var clean_number_progress = ""+value;
	var re = new RegExp(",","g");
	return clean_number_progress.replace(re,"");
}
function sanitizeString(){ /// FOR SECURITY

}

function Sum(sum_fn) {
    var fieldname = sum_fn;
    var summation = 0;
    if (fieldname.indexOf("@") >= 0) {
        fieldname = fieldname.replace("@", "");
    }
    summation = summation + Number($('[name="' + fieldname + '"]').val().replace(/,/g,""));

    $('[rep-original-name="' + fieldname + '"]').each(function(eqi) {
        summation = summation + Number($(this).val().replace(/,/g,""));
    });

    return summation;
}

function ThisDate(this_date) {
    var this_time = this_date.match(/..:..:..\s[A-Za-z]{2}|..:..\s[A-Za-z]{2}|..:..:..|..:../g);
    if(this_time != null){
        var this_time2 = this_time[0].replace(/\s[A-Za-z]{2}/g,"");
        var this_time_splitted = this_time2.split(":");
        var time_hours = "";
        var time_minutes = "";
        var time_seconds = "";
        if(typeof this_time_splitted[0] != "undefined"){ //hours
            time_hours = this_time_splitted[0];
        }
        if(typeof this_time_splitted[1] != "undefined"){ //minutes
            time_minutes = this_time_splitted[1];
        }
        var dis_date = this_date.replace(this_time[0],"");
        var this_new_date = new Date($.trim(dis_date));

        this_new_date = new Date(this_new_date.setHours(time_hours));

        this_new_date = new Date(this_new_date.setMinutes(time_minutes));
    }else{
        var this_new_date = new Date(this_date);
    }


    // var converted_date = (this_new_date.getFullYear())+"-"+(this_new_date.getMonth()+1)+"-"+(this_new_date.getDate());
    if (this_new_date == "Invalid Date") {
        return this_new_date;
    } else {
        return this_new_date;
    }
}
Number.prototype.currencyFormat = function(){
   // (?<=\d)(?=(\d\d\d)+(?!\d))
   // return this.toString().replace(/(\d)(?=(\d{3})+(?!\d))/g, "$1,");
   // console.log(this)
   // console.log("ow")

   var float_value = this.toString().split(".");
   var integer = float_value[0];
   var decimal = "";
   if(float_value.length == 2){
        decimal = float_value[1];
        integer = integer.split(/(?=(?:...)*$)/).join(",");
        return integer+"."+decimal;
   }else{
        integer = integer.split(/(?=(?:...)*$)/).join(",");
        return integer+".00";
   }
};
Date.prototype.formatDate = function(format) {
    if (this == "Invalid Date") {
        return this;
    } else {
        timestamp = this;
        // http://kevin.vanzonneveld.net
        // +   original by: Carlos R. L. Rodrigues (http://www.jsfromhell.com)
        // +      parts by: Peter-Paul Koch (http://www.quirksmode.org/js/beat.html)
        // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
        // +   improved by: MeEtc (http://yass.meetcweb.com)
        // +   improved by: Brad Touesnard
        // +   improved by: Tim Wiel
        // +   improved by: Bryan Elliott
        // +   improved by: David Randall
        // +      input by: Brett Zamir (http://brett-zamir.me)
        // +   bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
        // +   improved by: Theriault
        // +  derived from: gettimeofday
        // +      input by: majak
        // +   bugfixed by: majak
        // +   bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
        // +      input by: Alex
        // +   bugfixed by: Brett Zamir (http://brett-zamir.me)
        // +   improved by: Theriault
        // +   improved by: Brett Zamir (http://brett-zamir.me)
        // +   improved by: Theriault
        // +   improved by: Thomas Beaucourt (http://www.webapp.fr)
        // +   improved by: JT
        // +   improved by: Theriault
        // +   improved by: Rafał Kukawski (http://blog.kukawski.pl)
        // +   bugfixed by: omid (http://phpjs.org/functions/380:380#comment_137122)
        // +      input by: Martin
        // +      input by: Alex Wilson
        // +      input by: Haravikk
        // +   improved by: Theriault
        // +   bugfixed by: Chris (http://www.devotis.nl/)
        // %        note 1: Uses global: php_js to store the default timezone
        // %        note 2: Although the function potentially allows timezone info (see notes), it currently does not set
        // %        note 2: per a timezone specified by date_default_timezone_set(). Implementers might use
        // %        note 2: this.php_js.currentTimezoneOffset and this.php_js.currentTimezoneDST set by that function
        // %        note 2: in order to adjust the dates in this function (or our other date functions!) accordingly
        // *     example 1: date('H:m:s \\m \\i\\s \\m\\o\\n\\t\\h',  );
        // *     returns 1: '09:09:40 m is month'
        // *     example 2: date('F j, Y, g:i a', 1062462400);
        // *     returns 2: 'September 2, 2003, 2:26 am'
        // *     example 3: date('Y W o', 1062462400);
        // *     returns 3: '2003 36 2003'
        // *     example 4: x = date('Y m d', (new Date()).getTime()/1000);
        // *     example 4: (x+'').length == 10 // 2009 01 09
        // *     returns 4: true
        // *     example 5: date('W', 1104534000);
        // *     returns 5: '53'
        // *     example 6: date('B t', 1104534000);
        // *     returns 6: '999 31'
        // *     example 7: date('W U', 1293750000.82); // 2010-12-31
        // *     returns 7: '52 1293750000'
        // *     example 8: date('W', 1293836400); // 2011-01-01
        // *     returns 8: '52'
        // *     example 9: date('W Y-m-d', 1293974054); // 2011-01-02
        // *     returns 9: '52 2011-01-02'
        var that = this,
                jsdate,
                f,
                // Keep this here (works, but for code commented-out
                // below for file size reasons)
                //, tal= [],
                txt_words = ["Sun", "Mon", "Tues", "Wednes", "Thurs", "Fri", "Satur", "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
                // trailing backslash -> (dropped)
                // a backslash followed by any character (including backslash) -> the character
                // empty string -> empty string
                formatChr = /\\?(.?)/gi,
                formatChrCb = function(t, s) {
                    return f[t] ? f[t]() : s;
                },
                _pad = function(n, c) {
                    n = String(n);
                    while (n.length < c) {
                        n = '0' + n;
                    }
                    return n;
                };
        f = {
            // Day
            d: function() { // Day of month w/leading 0; 01..31
                return _pad(f.j(), 2);
            },
            D: function() { // Shorthand day name; Mon...Sun
                return f.l().slice(0, 3);
            },
            j: function() { // Day of month; 1..31
                return jsdate.getDate();
            },
            l: function() { // Full day name; Monday...Sunday
                return txt_words[f.w()] + 'day';
            },
            N: function() { // ISO-8601 day of week; 1[Mon]..7[Sun]
                return f.w() || 7;
            },
            S: function() { // Ordinal suffix for day of month; st, nd, rd, th
                var j = f.j(),
                        i = j % 10;
                if (i <= 3 && parseInt((j % 100) / 10, 10) == 1) {
                    i = 0;
                }
                return ['st', 'nd', 'rd'][i - 1] || 'th';
            },
            w: function() { // Day of week; 0[Sun]..6[Sat]
                return jsdate.getDay();
            },
            z: function() { // Day of year; 0..365
                var a = new Date(f.Y(), f.n() - 1, f.j()),
                        b = new Date(f.Y(), 0, 1);
                return Math.round((a - b) / 864e5);
            },
            // Week
            W: function() { // ISO-8601 week number
                var a = new Date(f.Y(), f.n() - 1, f.j() - f.N() + 3),
                        b = new Date(a.getFullYear(), 0, 4);
                return _pad(1 + Math.round((a - b) / 864e5 / 7), 2);
            },
            // Month
            F: function() { // Full month name; January...December
                return txt_words[6 + f.n()];
            },
            m: function() { // Month w/leading 0; 01...12
                return _pad(f.n(), 2);
            },
            M: function() { // Shorthand month name; Jan...Dec
                return f.F().slice(0, 3);
            },
            n: function() { // Month; 1...12
                return jsdate.getMonth() + 1;
            },
            t: function() { // Days in month; 28...31
                return (new Date(f.Y(), f.n(), 0)).getDate();
            },
            // Year
            L: function() { // Is leap year?; 0 or 1
                var j = f.Y();
                return j % 4 === 0 & j % 100 !== 0 | j % 400 === 0;
            },
            o: function() { // ISO-8601 year
                var n = f.n(),
                        W = f.W(),
                        Y = f.Y();
                return Y + (n === 12 && W < 9 ? 1 : n === 1 && W > 9 ? -1 : 0);
            },
            Y: function() { // Full year; e.g. 1980...2010
                return jsdate.getFullYear();
            },
            y: function() { // Last two digits of year; 00...99
                return f.Y().toString().slice(-2);
            },
            // Time
            a: function() { // am or pm
                return jsdate.getHours() > 11 ? "pm" : "am";
            },
            A: function() { // AM or PM
                return f.a().toUpperCase();
            },
            B: function() { // Swatch Internet time; 000..999
                var H = jsdate.getUTCHours() * 36e2,
                        // Hours
                        i = jsdate.getUTCMinutes() * 60,
                        // Minutes
                        s = jsdate.getUTCSeconds(); // Seconds
                return _pad(Math.floor((H + i + s + 36e2) / 86.4) % 1e3, 3);
            },
            g: function() { // 12-Hours; 1..12
                return f.G() % 12 || 12;
            },
            G: function() { // 24-Hours; 0..23
                return jsdate.getHours();
            },
            h: function() { // 12-Hours w/leading 0; 01..12
                return _pad(f.g(), 2);
            },
            H: function() { // 24-Hours w/leading 0; 00..23
                return _pad(f.G(), 2);
            },
            i: function() { // Minutes w/leading 0; 00..59
                return _pad(jsdate.getMinutes(), 2);
            },
            s: function() { // Seconds w/leading 0; 00..59
                return _pad(jsdate.getSeconds(), 2);
            },
            u: function() { // Microseconds; 000000-999000
                return _pad(jsdate.getMilliseconds() * 1000, 6);
            },
            // Timezone
            e: function() { // Timezone identifier; e.g. Atlantic/Azores, ...
                // The following works, but requires inclusion of the very large
                // timezone_abbreviations_list() function.

                throw 'Not supported (see source code of date() for timezone on how to add support)';
            },
            I: function() { // DST observed?; 0 or 1
                // Compares Jan 1 minus Jan 1 UTC to Jul 1 minus Jul 1 UTC.
                // If they are not equal, then DST is observed.
                var a = new Date(f.Y(), 0),
                        // Jan 1
                        c = Date.UTC(f.Y(), 0),
                        // Jan 1 UTC
                        b = new Date(f.Y(), 6),
                        // Jul 1
                        d = Date.UTC(f.Y(), 6); // Jul 1 UTC
                return ((a - c) !== (b - d)) ? 1 : 0;
            },
            O: function() { // Difference to GMT in hour format; e.g. +0200
                var tzo = jsdate.getTimezoneOffset(),
                        a = Math.abs(tzo);
                return (tzo > 0 ? "-" : "+") + _pad(Math.floor(a / 60) * 100 + a % 60, 4);
            },
            P: function() { // Difference to GMT w/colon; e.g. +02:00
                var O = f.O();
                return (O.substr(0, 3) + ":" + O.substr(3, 2));
            },
            T: function() { // Timezone abbreviation; e.g. EST, MDT, ...
                // The following works, but requires inclusion of the very
                // large timezone_abbreviations_list() function.

                return 'UTC';
            },
            Z: function() { // Timezone offset in seconds (-43200...50400)
                return -jsdate.getTimezoneOffset() * 60;
            },
            // Full Date/Time
            c: function() { // ISO-8601 date.
                return 'Y-m-d\\TH:i:sP'.replace(formatChr, formatChrCb);
            },
            r: function() { // RFC 2822
                return 'D, d M Y H:i:s O'.replace(formatChr, formatChrCb);
            },
            U: function() { // Seconds since UNIX epoch
                return jsdate / 1000 | 0;
            }
        };
        this.date = function(format, timestamp) {
            that = this;
            jsdate = (timestamp === undefined ? new Date() : // Not provided
                    (timestamp instanceof Date) ? new Date(timestamp) : // JS Date()
                    new Date(timestamp * 1000) // UNIX timestamp (auto-convert to int)
                    );
            return format.replace(formatChr, formatChrCb);
        };
        return this.date(format, timestamp);
    }//end of if
}
Date.prototype.diffDaysIn = function(date2) {
    if (typeof date2 != "undefined" && date2.length >= 1 && this != "Invalid Date") {
        var date2_dt_obj = new Date(date2);
        var t2 = date2_dt_obj.getTime();
        var t1 = this.getTime();
        return Math.abs(parseInt((t1 - t2) / (24 * 3600 * 1000)));
    } else {
        return "";
    }
}
Date.prototype.diffWeeksIn = function(date2) {
    if (typeof date2 != "undefined" && date2.length >= 1 && this != "Invalid Date") {
        var date2_dt_obj = new Date(date2);
        var t2 = date2_dt_obj.getTime();
        var t1 = this.getTime();

        return Math.abs(parseInt((t1 - t2) / (24 * 3600 * 1000 * 7)));
    } else {
        return "";
    }
}
Date.prototype.diffMonthsIn = function(date2) {
    if (typeof date2 != "undefined" && date2.length >= 1 && this != "Invalid Date") {
        var date2_dt_obj = new Date(date2);
        var d1Y = this.getFullYear();
        var d2Y = date2_dt_obj.getFullYear();
        var d1M = this.getMonth();
        var d2M = date2_dt_obj.getMonth();
        return Math.abs((d2M + 12 * d2Y) - (d1M + 12 * d1Y));
    } else {
        return "";
    }
}

Date.prototype.diffYearsIn = function(date2) {
    if (typeof date2 != "undefined" && date2.length >= 1 && this != "Invalid Date") {
        var date2_dt_obj = new Databasee(date2);
        return Math.abs(date2_dt_obj.getFullYear() - this.getFullYear());
    } else {
        return "";
    }
}

Date.prototype.adjustSeconds = function(value) {
    if ($.isNumeric(value)) {
        var new_date = this.setSeconds(parseInt(this.getSeconds()) + parseInt(value));
        var obj_new_date = new Date(new_date);
        return obj_new_date;
    } else {
        return "";
    }
}
Date.prototype.adjustMinutes = function(value) {
    if ($.isNumeric(value)) {
        var new_date = this.setMinutes(parseInt(this.getMinutes()) + parseInt(value));
        var obj_new_date = new Date(new_date);
        return obj_new_date;
    } else {
        return "";
    }
}
Date.prototype.adjustHours = function(value) {
    if ($.isNumeric(value)) {
        var new_date = this.setHours(parseInt(this.getHours()) + parseInt(value));
        var obj_new_date = new Date(new_date);
        return obj_new_date;
    } else {
        return "";
    }
}
Date.prototype.adjustDay = function(value) {
    if ($.isNumeric(value)) {
        var new_date = this.setDate(parseInt(this.getDate()) + parseInt(value));
        var obj_new_date = new Date(new_date);
        return obj_new_date;
    } else {
        return "";
    }
}
Date.prototype.adjustMonth = function(value) {
    if ($.isNumeric(value)) {
        var new_date = this.setMonth(parseInt(this.getMonth()) + parseInt(value));
        var obj_new_date = new Date(new_date);
        return obj_new_date;
    } else {
        return "";
    }
}
Date.prototype.adjustYear = function(value) {
    if ($.isNumeric(value)) {
        var new_date = this.setFullYear(parseInt(this.getFullYear()) + parseInt(value));
        var obj_new_date = new Date(new_date);
        return obj_new_date;
    } else {
        return "";
    }
}

function GivenIf(condition, valueTrue, valueFalse) {
    try {
        //splitted_condition_val = condition.split(/<=|>=|==|!=|<|>|\(|\)|!/g);
        if (eval(condition)) {
            return valueTrue;
        } else {
            return valueFalse;
        }
    } catch (error) {
        return "Conditional Error!";
    }
}
// function StrConcat() {
//     try {
//         var collect_strings = "";
//         for (var ctr = 0; ctr < arguments.length; ctr++) {
//             //
//             collect_strings += arguments[ctr];
//         }
//         return collect_strings;
//     } catch (error) {
//         console.log("ERROR ON USAGE OF CONCATENATION");
//     }
// }
function Lookup(formName, returnField, filterName, filterValue) {
    try {
        $.get("ajax/", {
            "access_formula": "Lookup",
            "formName": formName,
            "returnField": returnField,
            "filterName": filterName,
            "filterValue": filterValue
        }, function(echoData) {

        });
    } catch (error) {

    }
}

function StrLeft(str_val, str_length) {
    var str_to_process = String(str_val);
    return str_to_process.substr(0, str_length);
}
function StrRight(str_val, str_length) {
    var str_to_process = String(str_val);
    var start = (str_to_process.length - (str_length));
    if (start <= -1) {
        start = 0;
    }
    return str_to_process.substr(start, str_length);
}
function StrCount(str_val) {
    if (typeof str_val != "undefined") {
        return String(str_val).length;
    }
}
function StrConcat(){
    var args = arguments;//infinite argument
    var collect_strings = "";
    for(var ctr = 0 ; ctr < args.length ; ctr++){
        collect_strings = collect_strings + args[ctr];
    }
    return collect_strings;
}
function StrGet(str_val, str_istart, str_char_len) {
    if (typeof str_val == "undefined") {
        return "";
    }
    var string_val = String(str_val);
    var string_start_index = Number(str_istart);
    if (string_start_index <= 0) {
        return "";
    }
    if (typeof str_char_len == "undefined") {
        return String(string_val.charAt((Number(str_istart) - 1)));
    } else {
        return string_val.substr((Number(str_istart) - 1), Number(str_char_len));
    }
}